"""
核心模型类
"""
from django.apps import apps
from django.db import models
from django.db.models import QuerySet
from settings.conf_base import conf, AUTH_USER_MODEL


class SoftDeleteQuerySet(QuerySet):
    pass


class SoftDeleteManager(models.Manager):
    """支持软删除"""

    def __init__(self, *args, **kwargs):
        self.__add_is_del_filter = False
        super(SoftDeleteManager, self).__init__(*args, **kwargs)

    def filter(self, *args, **kwargs):
        """
        不传is_del字段时 默认筛选is_del=False;
        筛选未删除数据：不传is_del 或 is_del=False
        筛选已删除数据：is_del=True
        全部数据：is_del='all'
        """

        if 'is_del' in kwargs:
            self.__add_is_del_filter = True
            if kwargs['is_del'] == 'all':
                kwargs.pop('is_del')
        else:
            self.__add_is_del_filter = False
        return super(SoftDeleteManager, self).filter(*args, **kwargs)

    def get_queryset(self):
        if self.__add_is_del_filter:
            # return SoftDeleteQuerySet(self.model, using=self._db).exclude(is_del=False)
            return SoftDeleteQuerySet(self.model, using=self._db)
        return SoftDeleteQuerySet(self.model).exclude(is_del=True)

    def get_by_natural_key(self, name):
        return SoftDeleteQuerySet(self.model).get(username=name)


class SoftDeleteModel(models.Model):
    """
    软删除模型
    一旦继承,就将开启软删除
    """
    is_del = models.BooleanField(verbose_name='是否软删除', help_text='是否软删除', default=False, db_index=True)
    objects = SoftDeleteManager()

    class Meta:
        abstract = True
        verbose_name = '软删除模型'
        verbose_name_plural = verbose_name

    def delete(self, using=None, soft_delete=True, *args, **kwargs):
        """
        重写删除方法,直接开启软删除
        """
        self.is_del = True
        self.save(using=using)


class CoreModel(models.Model):
    """
    核心标准抽象模型模型,可直接继承使用
    增加审计字段, 覆盖字段时, 字段名称请勿修改, 必须统一审计字段名称
    """
    id = models.BigAutoField(primary_key=True, help_text='Id', verbose_name='Id')
    creator = models.ForeignKey(to=AUTH_USER_MODEL, related_query_name='creator_query', null=True,
                                verbose_name='创建人', help_text='创建人', on_delete=models.SET_NULL, db_constraint=False)
    update_time = models.DateTimeField(auto_now=True, null=True, blank=True, help_text='修改时间', verbose_name='修改时间')
    create_time = models.DateTimeField(auto_now_add=True, null=True, blank=True, help_text='创建时间', verbose_name='创建时间')

    class Meta:
        abstract = True
        verbose_name = '核心模型'
        verbose_name_plural = verbose_name


class DeptBelongModel(models.Model):
    dept_belong_id = models.IntegerField(help_text='数据归属地区', null=True, blank=True, verbose_name='数据归属地区')

    class Meta:
        abstract = True
        verbose_name = '数据归属地区模型'
        verbose_name_plural = verbose_name


def get_all_models_objects(model_name=None):
    """
    获取所有 models 对象
    :return: {}
    """
    conf.ALL_MODELS_OBJECTS = dict()
    if not conf.ALL_MODELS_OBJECTS:
        all_models = apps.get_models()
        for item in list(all_models):
            table = {
                'tableName': item._meta.verbose_name,
                'table': item.__name__,
                'tableFields': []
            }
            for field in item._meta.fields:
                fields = {
                    'title': field.verbose_name,
                    'field': field.name
                }
                table['tableFields'].append(fields)
            conf.ALL_MODELS_OBJECTS.setdefault(item.__name__, {'table': table, 'object': item})
    if model_name:
        return conf.ALL_MODELS_OBJECTS[model_name] or {}
    return conf.ALL_MODELS_OBJECTS or {}


def get_fieds_values(instance):
    data = dict()
    for k, v in instance.__dict__.items():
        if k in ('get_date', 'save_date'):
            data[k] = v.strftime('%Y-%m-%d') if v else None
            continue
        if not k.startswith('_') and k not in ('create_time', 'update_time', 'is_del', 'id'):
            data[k] = v
    return data